package com.kjs.common.tools;

import com.alibaba.fastjson.JSONObject;
import com.kjs.common.resultModel.JsonWebToken;
import com.kjs.common.consts.ResultConst;
import com.kjs.common.exception.JwtAuthenFailureException;
import io.jsonwebtoken.*;

import javax.servlet.ServletException;
import java.util.Date;

/**
 * jwt的token助手
 *
 * @author xuedingjiexueergou@gmail.com
 * @date 2018/10/12 13:59
 */
public class JwtTokenUtil {
    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims getClaimsFromToken(String secret, String token) throws ServletException {
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(secret.getBytes()).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            if (e instanceof ExpiredJwtException) {
                throw new JwtAuthenFailureException(ResultConst.ERR_AUTH_JWT_EXPIRE);
            }
            claims = null;
        }
        return claims;
    }

    /**
     * 判断令牌是否过期
     *
     * @param claims 令牌
     * @return 是否过期
     */
    public static boolean isTokenExpired(Claims claims) {
        try {
            //Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

    public static String getAuthIdFromToken(Claims claims) {
        return getValueFromToken(claims, "id");
    }

    public static String getRandomFromToken(Claims claims) {
        return getValueFromToken(claims, "random");
    }

    public static String getValueFromToken(Claims claims, String key) {
        if (claims == null) return null;
        Object obj = claims.get(key);
        if (obj == null) return null;
        return obj.toString();
    }

    /**
     * 创建一个access_token
     *
     * @param jwtIss 发行者
     * @param exp    有效期
     * @param random 随机数
     * @param authId 登录id
     * @param secret 应用secret
     * @return token
     */
    public static String accessToken(String jwtIss, long exp, String random, String authId, String secret) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
                .claim("random", random)
                .claim("id", authId) // 认证Id 内含 用户信息
                .setIssuer(jwtIss)
                .setExpiration(new Date(exp))
                .signWith(signatureAlgorithm, secret.getBytes());
        return builder.compact();
    }

    /**
     * 把jwt构造的json进行转换
     *
     * @param token json字符串
     * @return token对象
     */
    public static JsonWebToken convert(String token) {
        JSONObject jo = JSONObject.parseObject(token);
        return (JsonWebToken) JSONObject.parseObject(jo.toJSONString(), JsonWebToken.class);
    }
}
